﻿using System;
using System.Collections;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Runtime.InteropServices;

namespace codeding.KMeans.DataStructures.Lists
{
    //public enum DoiTuongStatus
    //{
    //    NotDefined = -1,
    //    Disable = 0,
    //    Enable = 1
    //}
    public class DoiTuong
    {
        #region ID property
        public Guid ID
        {
            get
            {
                if (_DataRow["ID"] is Guid)
                    return (Guid)_DataRow["ID"];
                else
                    return Guid.Empty;
            }
            set
            {
                _DataRow["ID"] = value;
            }
        }
        #endregion

        #region Disable property
        public bool Disable
        {
            get
            {
                if (_DataRow["Disable"] is bool)
                    return (bool)_DataRow["Disable"];
                else
                    return false;
            }
            set
            {
                _DataRow["Disable"] = value;
            }
        }
        #endregion

        public static string _ConnectionString
        {
            get
            {
                //string connStr = ConfigurationSettings.AppSettings["FilmDBConnectionString"].ToString();
                //return @"Data Source=KUTE\SQL2008;Initial Catalog=FilmDB;uid=sa;pwd=1";
                return "Data Source=117.6.85.20;Initial Catalog=FilmDB_Full;uid=sa;pwd=sqlP2ssw0rd";
            }
        }

        protected DataRow _DataRow = null;
        public DataRow DataRow
        {
            get
            {
                return _DataRow;
            }
            set
            {
                _DataRow = value;
            }
        }

        //public virtual void InsertToDB()
        //{
        //    SqlConnection con = new SqlConnection(DoiTuong._ConnectionString);
        //    try
        //    {
        //        con.Open();
        //        SqlCommand cmd = con.CreateCommand();
        //        InsertToDB(cmd);
        //    }
        //    catch (SqlException sqlEx)
        //    {
        //        throw new CustomException(CustomException.GetSqlExceptionMessage(sqlEx));
        //    }
        //    catch (Exception ex)
        //    {
        //        if (ex is CustomException) throw ex;
        //        else
        //        {
        //            throw new Exception(ex.Message);
        //        }
        //    }
        //    finally
        //    {
        //        con.Close();
        //    }
        //}
        //public virtual void UpdateToDB()
        //{
        //    SqlConnection con = new SqlConnection(_ConnectionString);
        //    try
        //    {
        //        con.Open();
        //        SqlCommand cmd = con.CreateCommand();
        //        UpdateToDB(cmd);
        //    }
        //    catch (SqlException sqlEx)
        //    {
        //        throw new CustomException(CustomException.GetSqlExceptionMessage(sqlEx));
        //    }
        //    catch (Exception ex)
        //    {
        //        if (ex is CustomException) throw ex;
        //        else
        //        {
        //            throw new Exception(ex.Message);
        //        }
        //    }
        //    finally
        //    {
        //        con.Close();
        //    }
        //}

        //public virtual void InsertToDB(SqlCommand cmd)
        //{
        //    if (cmd.Connection.State != ConnectionState.Open) throw new CustomException("Chưa mở connection");
        //    string values = ""; string listOfColumns = "";
        //    cmd.Parameters.Clear();
        //    foreach (DataColumn column in this.DataRow.Table.Columns)
        //    {
        //        if (column.ColumnName != "LastUpdated" && column.ColumnName != "ID")
        //        {
        //            values = values + "@" + column.ColumnName + ", ";
        //            listOfColumns = listOfColumns + column.ColumnName + ", ";
        //            cmd.Parameters.AddWithValue(column.ColumnName, this.DataRow[column.ColumnName]);
        //        }
        //    }

        //    if (values.EndsWith(", ")) values = values.Substring(0, values.Length - 2);
        //    if (listOfColumns.EndsWith(", ")) listOfColumns = listOfColumns.Substring(0, listOfColumns.Length - 2);

        //    cmd.CommandText = string.Format("INSERT INTO [{0}]({1}) VALUES({2})",
        //                                        this.DataRow.Table.TableName, listOfColumns, values);
        //    cmd.ExecuteNonQuery();
        //    if (this.DataRow.Table.Rows.IndexOf(this.DataRow) < 0) this.DataRow.Table.Rows.Add(this.DataRow);
        //}
        //public virtual void UpdateToDB(SqlCommand cmd)
        //{
        //    if (cmd.Connection.State != ConnectionState.Open) throw new CustomException("Chưa mở connection");
        //    string values = "";
        //    cmd.Parameters.Clear();
        //    foreach (DataColumn column in this.DataRow.Table.Columns)
        //    {
        //        if (column.ColumnName != "LastUpdated" && column.ColumnName != "ID")
        //        {
        //            values += string.Format("{0} = @{0}, ", column.ColumnName);
        //            if (this.DataRow[column.ColumnName] is Guid && (Guid)this.DataRow[column.ColumnName] == Guid.Empty)
        //            {
        //                cmd.Parameters.AddWithValue(column.ColumnName, DBNull.Value);
        //            }
        //            else
        //            {
        //                cmd.Parameters.AddWithValue(column.ColumnName, this.DataRow[column.ColumnName]);
        //            }
        //        }
        //    }

        //    if (values.EndsWith(", ")) values = values.Substring(0, values.Length - 2);

        //    cmd.CommandText = string.Format("UPDATE [{0}] SET {1} WHERE ID = '{2}'",
        //                                        this.DataRow.Table.TableName,
        //                                        values,
        //                                        this.DataRow["ID"]);
        //    cmd.ExecuteNonQuery();
        //}

        //public virtual void DeleteFromDB()
        //{
        //    SqlConnection con = new SqlConnection(_ConnectionString);
        //    try
        //    {
        //        con.Open();
        //        SqlCommand cmd = con.CreateCommand();
        //        cmd.CommandText = string.Format("DELETE FROM {0} WHERE ID = '{1}'",
        //                                            this.DataRow.Table.TableName,
        //                                            this.DataRow["ID"]);
        //        cmd.ExecuteNonQuery();
        //        _DataRow.Delete();
        //    }
        //    catch (SqlException sqlEx)
        //    {
        //        throw new CustomException(CustomException.GetSqlExceptionMessage(sqlEx));
        //    }
        //    catch (Exception ex)
        //    {
        //        if (ex is CustomException) throw ex;
        //        else
        //        {
        //            throw new Exception(ex.Message);
        //        }
        //    }
        //    finally
        //    {
        //        con.Close();
        //    }
        //}
        //public virtual void DeleteFromDB(SqlCommand cmd)
        //{
        //    try
        //    {
        //        cmd.CommandText = string.Format("DELETE FROM {0} WHERE ID = '{1}'",
        //                                            this.DataRow.Table.TableName,
        //                                            this.DataRow["ID"]);
        //        cmd.ExecuteNonQuery();
        //        _DataRow.Delete();
        //    }
        //    catch (SqlException sqlEx)
        //    {
        //        throw new CustomException(CustomException.GetSqlExceptionMessage(sqlEx));
        //    }
        //    catch (Exception ex)
        //    {
        //        if (ex is CustomException) throw ex;
        //        else
        //        {
        //            throw new Exception(ex.Message);
        //        }
        //    }
        //    finally
        //    {
        //        cmd.Connection.Close();
        //    }
        //}

        public DoiTuong()
        {
            //_DataRow = dataRow;
            //if (this.ID == Guid.Empty) this.ID = Guid.NewGuid();
        }
        public DoiTuong(DataRow dataRow)
        {
            _DataRow = dataRow;
            //if (this.ID == Guid.Empty) this.ID = Guid.NewGuid();
        }
    }

    public abstract class DanhMucDoiTuong
    {
        #region TableName property
        public virtual string TableName
        {
            get
            {
                throw new CustomException("Chưa khởi tạo tên bảng cho danh mục. Lỗi lập trình: cần overide TableName");
            }
        }
        #endregion

        #region DataTable property
        public DataSet _DataSet;
        public DataTable DataTable
        {
            get
            {
                if (_DataSet == null || _DataSet.Tables.Count == 0)
                {
                    _DataSet = new DataSet();
                    LoadFromDB();
                }
                return _DataSet.Tables[0];
            }
        }
        #endregion

        #region DataView property
        private DataView _DataView;
        public DataView DataView
        {
            get
            {
                return _DataView;
            }
            set
            {
                _DataView = value;
            }
        }
        #endregion

        public delegate void ChangeHandler();
        public event ChangeHandler Change;
        protected SqlDataAdapter _DataAdapter = new SqlDataAdapter();

        protected DanhMucDoiTuong()
        {
        }

        public void LoadFromDB()
        {
            SqlConnection con = new SqlConnection(DoiTuong._ConnectionString);
            try
            {
                SqlCommand cmd = con.CreateCommand();

                switch (TableName)
                {
                    case "Function":
                        cmd.CommandText = string.Format("SELECT * FROM [{0}] ORDER BY ParentFunctionID", TableName);
                        break;
                    default:
                        cmd.CommandText = string.Format("SELECT * FROM {0}", TableName);
                        break;
                }

                _DataAdapter.SelectCommand = cmd;
                _DataSet.Clear();
                _DataAdapter.Fill(_DataSet, TableName);
            }
            catch (SqlException sqlEx)
            {
                throw new CustomException(CustomException.GetSqlExceptionMessage(sqlEx));
            }
            catch (Exception ex)
            {
                if (ex is CustomException) throw ex;
                else
                {
                    throw new Exception(ex.Message);
                }
            }
            finally
            {
            }
        }

        public void InsertToDB(DoiTuong doiTuong)
        {
            if (DataTable.Rows.IndexOf(doiTuong.DataRow) < 0) DataTable.Rows.Add(doiTuong.DataRow);
        }

        public void UpdateToDB()
        {
            try
            {
                SqlCommandBuilder commandBuilder = new SqlCommandBuilder((SqlDataAdapter)_DataAdapter);
                commandBuilder.DataAdapter.Update(_DataSet, TableName);
                this.DataTable.AcceptChanges();
                try
                {
                    if (Change != null) Change();
                }
                catch (Exception ex)
                {
                }
            }
            catch (SqlException sqlEx)
            {
                throw new CustomException(CustomException.GetSqlExceptionMessage(sqlEx));
            }
            catch (Exception ex)
            {
                if (ex is CustomException) throw ex;
                else
                {
                    throw new Exception(ex.Message);
                }
            }
        }

        public int Count
        {
            get
            {
                return this.DataView.Count;
            }
        }
        protected DataRow[] GetDataRows(string filterExpression)
        {
            return DataTable.Select(filterExpression);
        }

        protected DataRow[] GetDataRows(string property, object value)
        {
            string filterExpression = "";
            if (value is string)
            {
                value = (value as string).Replace("'", "''");
                filterExpression = string.Format("{0} = '{1}'", property, value);
            }
            else if (value is Guid)
                filterExpression = string.Format("{0} = '{1}'", property, value);
            else
                filterExpression = string.Format("{0} = {1}", property, value);

            return DataTable.Select(filterExpression);
        }

        public static void ReloadAllDanhMuc()
        {
            try
            {
                DanhMucMovie.Instance.LoadFromDB();
                DanhMucRatings.Instance.LoadFromDB();
                DanhMucUserAccount.Instance.LoadFromDB();
                //DanhMucKho.Instance.LoadFromDB();
                //DanhMucPhuongThucThanhToanMuaHang.Instance.LoadFromDB();
                //DanhMucPhuongThucThanhToanBanHang.Instance.LoadFromDB();
                //DanhMucMayTinh.Instance.LoadFromDB();
            }
            catch (Exception ex)
            {
                if (ex is CustomException) throw ex;
                else
                {
                    throw new Exception(ex.Message);
                }
            }
        }
    }
}
